#ifndef OTAUPDATETHREAD_H
#define OTAUPDATETHREAD_H

#include <QObject>
#include <QThread>
#include "otabase.h"

class OTAUpdateThread : public QThread, public OTABase
{
    Q_OBJECT

#define BLOCK_LEN   4096

public:
    explicit OTAUpdateThread(QObject *parent = nullptr);

    ~OTAUpdateThread();

    void run();

    QByteArray readAll();

signals:
    void OTASerialSendData(QByteArray data);
    void OTALog(QString string);
    void OTASetBlock(qsizetype block, qsizetype fsn);
    void OTASetAllBlock(qsizetype block);

private:
    // 确认版本
    void OTAComfirmVersionHandler();
    void OTAComfirmVersionResponse(QByteArray& data);

    // 解密
    void OTADecryptAuthHandler();
    void OTADecryptAuthResponse(QByteArray& data);

    void OTADecryptReturnHandler();
    void OTADecryptReturnResponse(QByteArray& data);

    // 发送更新信息
    void OTAUpdateMsgAppLenHandler();
    void OTAUpdateMsgOPLenHandler();
    void OTAUpdateMsgOPHandler();
    void OTAUpdateMsgResponse(QByteArray& data);

    // 发送BIN
    void OTAAppBinLenHandler();
    void OTAAppBinLenResponse(QByteArray& data);

    void OTAAppBinHandler();
    void OTAAppBinResponse(QByteArray& data);

    qsizetype AppBinBlockBegin();

    // 校验4K
    void OTA4KCRCHandler();
    void OTA4KCRCResponse(QByteArray& data);

    void OTACRCAllHandler();
    void OTACRCAllResponse(QByteArray& data);

    // 跳转APP
    void OTAJumpAppHandler();
    void OTAJumpAppResponse(QByteArray& data);

public slots:
    // 将串口接收到的数据，通过校验后，传过来
    void onOTADataReadySlot(QByteArray data);

    void onOTAUpdateStartSlot();
    void onOTAUpdateStopSlot();

private:
    quint8 m_cnt;
    quint8 m_isStop;
    quint8 m_updateStep; // 更新步骤
    quint16 m_appVer; // 软件版本
    quint16 m_bootVer;//bootloader版本
    QByteArray m_operatorMsg;  // 操作员信息
    quint8  m_OPFSN; // 操作员信息的帧序号

    quint16 m_4ksum;
    quint32 m_4kcrc32;

    // 解密状态以及随机码
    quint8 m_auth_sta;   // 认证状态, 有没有发出过随机码
    quint8 m_dec_sta;     // 解密状态
    quint8 m_random_code[4]; // 随机码
    quint8 m_decrypt_ret[6];  // 加密返回数

    // bin文件发送
    qsizetype m_BinBL;  // 块编号
    qsizetype m_BinBLLen; // 块长
    qsizetype m_BinFSN;  // 块帧序号
    qsizetype m_BinLen; // 总长度
    QByteArray m_Bin;  // 一块bin文件
    qsizetype m_BinAllBL; // 总块数

    QByteArray m_serialSendDataArr;
};

#endif // OTAUPDATETHREAD_H
